package protocol

import (
	"github.com/gorilla/websocket"
	"encoding/binary"
	"log"
)

type WebStream struct {
	conn   *websocket.Conn
}

//读取一个封包
func (self *WebStream) Read() (p *Packet, err error) {
	//读取包头
	_ , allMessageData,err :=self.conn.ReadMessage()
	if err != nil {
		return nil,err
	}

	allMessageLen := uint16(len(allMessageData))
	if allMessageLen < PacketHeaderSize {
		return nil, packetDataSizeInvalid
	}
	//读取包头
	headData := allMessageData[0:PacketHeaderSize]
	fullSize := binary.LittleEndian.Uint16(headData[PacketHeaderSize-2:PacketHeaderSize])
	dataSize := fullSize - PacketHeaderSize
	if dataSize < 0 {
		return nil, packetDataSizeInvalid
	}
	if dataSize > uint16(MaxPacketSize) {
		return nil, packetTooBig
	}

	packData := allMessageData[PacketHeaderSize:]
	//封装成Packet
	p = &Packet{}
	p.MainId = uint16(binary.LittleEndian.Uint16(packData[0:2]))
	p.SubId = uint16(binary.LittleEndian.Uint16(packData[2:4]))
	p.Data = packData[4:]
	return p, nil
}


//封包发送给socket
func (self *WebStream) Write(pkt *Packet) (err error) {
	userData := pkt.ToByteArray()
	//写MsgSize
	packetSize := len(userData) + PacketHeaderSize
	buffer := make([]byte, packetSize)
	//写入校验码
	binary.LittleEndian.PutUint16(buffer[0:2], uint16(100))
	//写入大小
	binary.LittleEndian.PutUint16(buffer[PacketHeaderSize-2:PacketHeaderSize], uint16(packetSize))
	//写数据
	buffer = append(buffer[:PacketHeaderSize], userData...)
	if err = self.conn.WriteMessage(websocket.BinaryMessage,buffer); err != nil {
		log.Println("写数据", err)
		return err
	}
	return nil
}

//关闭
func (self *WebStream) Close() error {
	return self.conn.Close()
}

// 取原始连接
func (self *WebStream) Raw() interface{} {
	if self.conn == nil {
		return nil
	}
	return self.conn
}


//封包流 relay模式: 在封包头有clientid信息
func NewWebStream(webcon *websocket.Conn) PacketStream {
	return &WebStream{
		conn: webcon,
	}
}
